home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DDJMAG / DDJ8801.ZIP / NARO.ZIP / LOADEXE.C < prev    next >
Text File  |  1987-10-30  |  3KB  |  140 lines

  1. /*
  2.     Copyright (C) 1987 Paradigm Systems Inc.  All rights reserved.
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <io.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <malloc.h>
  10. #include <dos.h>
  11.  
  12. #include "loc.h"
  13. #include "externs.h"
  14.  
  15.  
  16. char    *warn_str = "Warning: Unable to locate virtual segment %04X\n" ;
  17.  
  18. char    *load_exe_file()
  19. {
  20.     char    buf[128] ;
  21.     int    count, i ;
  22.     long    seek_pos ;
  23.     unsigned int    module_size, pseg, *reloc_ptr, segment ;
  24.     unsigned int    read_size, mem_size ;
  25.     char    *load_addr, *entry, *str ;
  26.  
  27.     EXE_HEADER    header;
  28.     SEG_DESCRIPTOR    *p ;
  29.  
  30.     /*
  31.         This function reads in the .EXE file and performs the fixup of any
  32.         segment references.
  33.     */
  34.  
  35.     /* Read in the .EXE file header information */
  36.     count = read(exe_file, (char *) &header, sizeof(header)) ;
  37.     if (count != sizeof(header))   {
  38.         perror(__FILE__) ;
  39.         exit(1) ;
  40.     }
  41.  
  42.     /* Exit if not a valid .EXE file */
  43.     if (header.signature != 0x5A4D)   {
  44.         perror("Not an .EXE file") ;
  45.         exit(1) ;
  46.     }
  47.  
  48.     /* Seek to the start of the load module */
  49.     if (lseek(exe_file, (long) header.header_size * 16, SEEK_SET) == -1L)  {
  50.         perror(__FILE__) ;
  51.         exit(1) ;
  52.     }
  53.  
  54.     /* Compute how much memory can be allocated for reads */
  55.     mem_size = 32 * 1024 ;
  56.     if (mem_size > _memavl())
  57.         mem_size = _memavl() ;
  58.         
  59.     /* Allocate the memory */
  60.     if ((load_addr = malloc(mem_size)) == NULL)   {
  61.         perror(__FILE__) ;
  62.         exit(1) ;
  63.     }
  64.  
  65.     while (1)   {
  66.         /* Read in a segment of the load module */
  67.         read_size = read(exe_file, load_addr, mem_size) ;
  68.         if (read_size == 0)   {
  69.             free(load_addr) ;
  70.             break ;
  71.         }
  72.  
  73.         /* Write it back out to the temporary file */
  74.         count = write(tmp_file, load_addr, read_size) ;
  75.         if (count != read_size)   {
  76.             perror(__FILE__) ;
  77.             exit(1) ;
  78.         }
  79.     }
  80.  
  81.     /* Find the relocation list */
  82.     if (lseek(exe_file, (long) header.first_reloc_item, SEEK_SET) == -1L)  {
  83.         perror(__FILE__) ;
  84.         exit(1) ;
  85.     }
  86.  
  87.     /* Perform the segment fixups on the temporary file */
  88.     for (i = 0; i < header.reloc_items; i++)   {
  89.         /* Read in a relocation item */
  90.         count = read(exe_file, (char *) &reloc_ptr, sizeof(reloc_ptr)) ;
  91.         if (count != sizeof(reloc_ptr))   {
  92.             perror(__FILE__) ;
  93.             exit(1) ;
  94.         }
  95.  
  96.         /* Compute the position of the fixup in the temporary file */
  97.         seek_pos = (long) FP_SEG(reloc_ptr) ;
  98.         seek_pos = seek_pos * 16 + FP_OFF(reloc_ptr) ;
  99.         if (lseek(tmp_file, seek_pos, SEEK_SET) == -1L)   {
  100.             perror(__FILE__) ;
  101.             exit(1) ;
  102.         }
  103.  
  104.         /* Read in the virtual segment from the fixup */
  105.         count = read(tmp_file, (char *) &segment, sizeof(segment)) ;
  106.         if (count != sizeof(segment))   {
  107.             perror(__FILE__) ;
  108.             exit(1) ;
  109.         }
  110.  
  111.         /* Perform the location */
  112.         if (locate_virtual_segment(segment, &pseg) == ERROR)
  113.             fprintf(stderr, warn_str, segment) ;
  114.  
  115.         segment = pseg ;
  116.  
  117.         /* Re-seek back to the fixup */
  118.         if (lseek(tmp_file, seek_pos, SEEK_SET) == -1L)   {
  119.             perror(__FILE__)  ;
  120.             exit(1) ;
  121.         }
  122.  
  123.         /* Write the physical segment number to the fixup */
  124.         count = write(tmp_file, (char *) &segment, sizeof(segment)) ;
  125.         if (count != sizeof(segment))   {
  126.             perror(__FILE__) ;
  127.             exit(1) ;
  128.         }
  129.     }
  130.  
  131.     /* Process the program entry point */
  132.     if (locate_virtual_segment(header.code_seg_disp, &pseg) == ERROR)
  133.         fprintf(stderr, "Warning: Unable to locate entry point\n") ;
  134.  
  135.     FP_SEG(entry) = pseg ;
  136.     FP_OFF(entry) = header.initial_pc ;
  137.  
  138.     return    entry ;
  139. }
  140.